<template>
  <div class="app-container">
    <el-form ref="problem" :model="problem" :rules="validateRules" label-width="120px" label-position="top">
      <el-form-item label="试题标题" prop="name">
        <el-input
          v-model="problem.name"
          type="text"
          placeholder="请输入试题标题（1~30个字）"
          maxlength="30"
          show-word-limit
        />
      </el-form-item>
      <el-form-item label="知识点" prop="categorys">
        <el-tag
          v-for="category in problem.categorys"
          :key="category.id"
          size="small"
          closable
          @close="handleClose(category.id)">
          {{ category.name }}
        </el-tag>
        <el-cascader-panel
          ref="categoryCascader"
          v-model="checkCategorys"
          :options="options"
          :props="{ multiple: true, checkStrictly: true, emitPath: false }"
          @change="handleChange"/>
      </el-form-item>

      <el-divider/>

      <el-form-item label="试题描述">
        <div class="editor-container">
          <markdown-editor ref="markdownEditor" v-model="problem.describe" height="800px"/>
        </div>
      </el-form-item>
      <el-form-item label="试题提示">
        <el-input v-model="problem.hint" type="textarea"/>
      </el-form-item>

      <el-divider/>

      <el-form-item label="时间限制" prop="timeLimit">
        <el-input v-model="problem.timeLimit" min="0" type="number">
          <template slot="append">ms</template>
        </el-input>
      </el-form-item>
      <el-form-item label="内存限制" prop="memoryLimit">
        <el-input v-model="problem.memoryLimit" min="0" type="number">
          <template slot="append">kB</template>
        </el-input>
      </el-form-item>
      <p>
        <span style="color: red">* </span>以上数值为 0 表示不受限制
      </p>

      <el-divider/>

      <el-form-item label="测试数据" prop="checkPoints">
        <el-table :data="problem.checkPoints" border fit highlight-current-row style="width: 100%">
          <el-table-column
            :index="indexMethod"
            type="index"
            align="center"
            label="序号"
            width="80"/>

          <el-table-column min-width="300px" label="输入">
            <template slot-scope="{row}">
              <template v-if="row.edit">
                <el-input
                  v-model="row.input"
                  :rows="2"
                  type="textarea"
                  class="edit-input"
                  size="small"/>
              </template>
              <span v-else>{{ row.input }}</span>
            </template>
          </el-table-column>
          <el-table-column min-width="300px" label="输出">
            <template slot-scope="{row}">
              <template v-if="row.edit">
                <el-input
                  v-model="row.output"
                  :rows="2"
                  type="textarea"
                  class="edit-input"
                  size="small"/>
              </template>
              <span v-else>{{ row.output }}</span>
            </template>
          </el-table-column>
          <el-table-column min-width="100px" label="分数">
            <template slot-scope="{row}">
              <template v-if="row.edit">
                <el-input
                  v-model="row.score"
                  type="number"
                  class="edit-input"
                  size="small"/>
              </template>
              <span v-else>{{ row.score }}</span>
            </template>
          </el-table-column>

          <el-table-column align="center" label="操作" width="200">
            <template slot-scope="{row}">
              <el-button
                v-if="row.edit"
                type="success"
                size="medium"
                icon="el-icon-check"
                @click="confirmEdit(row)"
              >
                保存
              </el-button>
              <el-button
                v-if="!row.edit"
                type="primary"
                size="mini"
                icon="el-icon-edit"
                @click="row.edit=!row.edit"
              >
                编辑
              </el-button>
              <el-button
                v-if="!row.edit"
                type="danger"
                size="mini"
                icon="el-icon-delete"
                @click="removeCheckPoint(row)"
              >
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>

      <el-form-item align="center">
        <el-button @click="addCheckpoint">新增测试点</el-button>
        <el-button :disabled="saveProblemBtn" type="success" @click="saveDraft">保存草稿</el-button>
        <el-button :disabled="saveProblemBtn" type="primary" @click="publishProblem">发布试题</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import MarkdownEditor from '@/components/MarkdownEditor'

import categoryApi from '@/api/oj/category'
import problemApi from '@/api/oj/problem'

const nameRule = (rule, value, callback) => {
  if (value.length < 1) {
    callback(new Error('试题标题长度不能小于1位'))
  }
  if (value.length > 30) {
    callback(new Error('试题标题长度不能大于30位'))
  }
  callback()
}

const categoryRule = (rule, value, callback) => {
  if (value.length === 0) {
    callback(new Error('请至少选择一个标签'))
  }
  if (value.length > 3) {
    callback(new Error('至多选择三个标签'))
  }
  callback()
}

const timeLimitRule = (rule, value, callback) => {
  if (value < 0) {
    callback(new Error('请输入不小于0的合法数值'))
  }
  callback()
}

const memoryLimitRule = (rule, value, callback) => {
  if (value < 0) {
    callback(new Error('请输入不小于0的合法数值'))
  }
  callback()
}

const checkPointRule = (rule, value, callback) => {
  callback()
}

export default {
  name: 'Form',
  components: { MarkdownEditor },
  data() {
    return {
      saveProblemBtn: false,
      problem: {
        id: null,
        number: 0,
        name: '',
        categorys: [],
        categoryIds: [],
        timeLimit: 1000,
        memoryLimit: 65536,
        describe: `这是一个试题模板。请在这里写题目描述。例如：本题目要求读入2个整数A和B，然后输出它们的和。

### 输入格式:

请在这里写输入格式。例如：输入在一行中给出2个绝对值不超过1000的整数A和B。

### 输出格式:

请在这里描述输出格式。例如：对每一组输入，在一行中输出A+B的值。

### 输入样例:

在这里给出一组输入。例如：

\`\`\`
18 -299
\`\`\`

### 输出样例:

在这里给出相应的输出。例如：

\`\`\`
-281
\`\`\`
`,
        hint: '',
        status: 0,
        checkPoints: [
          {
            edit: true,
            input: '',
            output: '',
            score: 0,
            key: 1
          },
          {
            edit: true,
            input: '',
            output: '',
            score: 0,
            key: 2
          },
          {
            edit: true,
            input: '',
            output: '',
            score: 0,
            key: 3
          }
        ]
      },
      validateRules: {
        name: [
          { required: true, trigger: 'blur', message: '请输入试题标题' },
          { validator: nameRule, trigger: 'blur' }
        ],
        categorys: [
          { required: true, trigger: 'blur', message: '请选择标签' },
          { validator: categoryRule, trigger: 'change' }
        ],
        timeLimit: [
          { required: true, trigger: 'blur', message: '请输入不小于0的合法数值' },
          { validator: timeLimitRule, trigger: 'blur' }
        ],
        memoryLimit: [
          { required: true, trigger: 'blur', message: '请输入不小于0的合法数值' },
          { validator: memoryLimitRule, trigger: 'blur' }
        ],
        checkPoints: [
          { required: true, trigger: 'blur', message: '请输入合法的测试数据' },
          { validator: checkPointRule, trigger: 'blur' }
        ]
      },
      checkCategorys: [],
      options: []
    }
  },

  created() {
    this.init()
  },

  mounted() {
    window.onbeforeunload = function(e) {
      e = e || window.event
      console.log(e)
      // 兼容IE8和Firefox 4之前的版本
      if (e) {
        e.returnValue = '关闭提示'
      }

      // Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
      return '关闭提示'
    }
  },

  methods: {

    init() {
      categoryApi.getAllCategorys().then(res => {
        this.options = res.result
      }).catch(error => {
        console.log(error)
      })

      console.log(this.$route.params)
      if (this.$route.params && this.$route.params.id) {
        const id = this.$route.params.id
        problemApi.getProblemInfo(id).then(res => {
          this.problem = res.result
          this.checkCategorys = this.problem.categorys.map(category => category.id)
        }).catch(error => {
          console.log(error)
        })
      }
    },

    handleSelectChange() {
      this.$forceUpdate()
    },

    indexMethod(index) {
      return index + 1
    },

    removeCheckPoint(checkpoint) {
      const index = this.problem.checkPoints.indexOf(checkpoint)
      if (index !== -1) {
        this.problem.checkPoints.splice(index, 1)
      }
    },

    addCheckpoint() {
      this.problem.checkPoints.push({
        edit: true,
        input: '',
        output: '',
        score: 0,
        key: Date.now()
      })
    },

    confirmEdit(row) {
      row.edit = false
    },

    saveDraft() {
      this.$refs['problem'].validate(valid => {
        if (valid) {
          this.problem.status = 0
          this.saveProblemBtn = true
          this.problem.categoryIds = this.problem.categorys.map(category => category.id)
          problemApi.createProblem(this.problem).then(res => {
            this.$message({
              type: 'success',
              message: res.result
            })
            this.saveProblemBtn = false
          }).catch(error => {
            console.log(error)
          })
        }
      })
    },

    publishProblem() {
      this.$refs['problem'].validate(valid => {
        if (valid) {
          this.problem.status = 1
          this.saveProblemBtn = true
          this.problem.categoryIds = this.problem.categorys.map(category => category.id)
          problemApi.createProblem(this.problem).then(res => {
            this.$message({
              type: 'success',
              message: '发布试题成功'
            })
            this.$router.push({ path: '/problem/details/' + res.result })
            this.saveProblemBtn = false
          }).catch(error => {
            console.log(error)
          })
        }
      })
    },

    handleChange(val) {
      this.problem.categorys = []
      this.$refs['categoryCascader'].getCheckedNodes().forEach(({
        value,
        label
      }) => this.problem.categorys.push({ id: value, name: label }))
    },

    handleClose(id) {
      this.checkCategorys = this.checkCategorys.filter(checkId => checkId !== id)
      this.problem.categorys = this.problem.categorys.filter(category => category.id !== id)
    }

  }
}
</script>
